package com.lonely.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetPartProcessDTO;
import com.lonely.goods.domain.entity.SysGoodsProcess;
import com.lonely.goods.service.IGoodsProcessService;
import com.lonely.order.domain.dto.order.CalculateWagesDTO;
import com.lonely.order.domain.entity.SysOrderPart;
import com.lonely.order.domain.entity.SysOrderProcess;
import com.lonely.order.domain.entity.SysOrderProcessItem;
import com.lonely.order.mapper.SysOrderProcessMapper;
import com.lonely.order.service.IOrderProcessItemService;
import com.lonely.order.service.IOrderProcessService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/2 10:50
 * @description: 订单工序服务实现类
 */
@Service
public class OrderProcessServiceImpl extends ServiceImpl<SysOrderProcessMapper, SysOrderProcess> implements IOrderProcessService {

    @Autowired
    private IGoodsProcessService goodsProcessService;

    @Autowired
    private IOrderProcessItemService orderProcessItemService;

    /**
     * 创建订单工序
     *
     * @param sysOrderPart
     * @param goodsPartId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrderProcess(SysOrderPart sysOrderPart, Long goodsPartId) {

        List<SysGoodsProcess> goodsProcesses = this.goodsProcessService.list(new LambdaQueryWrapper<SysGoodsProcess>()
                .eq(SysGoodsProcess::getGoodsPartId, goodsPartId)
        );
        if (CollUtil.isEmpty(goodsProcesses)) {
            return;
        }

        for (SysGoodsProcess goodsProcess : goodsProcesses) {
            SysOrderProcess sysOrderProcess = new SysOrderProcess();
            BeanUtils.copyProperties(goodsProcess, sysOrderProcess);
            sysOrderProcess.setOrderId(sysOrderPart.getOrderId());
            sysOrderProcess.setOrderPartId(sysOrderPart.getId());
            sysOrderProcess.setProduceOrderId(sysOrderPart.getProduceOrderId());
            sysOrderProcess.setCreateBy(SecurityUtils.getUserId());
            sysOrderProcess.setUpdateBy(SecurityUtils.getUserId());
            super.save(sysOrderProcess);

            // 创建订单工序明细
            this.orderProcessItemService.createOrderProcessItems(sysOrderProcess, goodsProcess.getId());
        }

    }

    /**
     * 查询商品报价单部件工序信息
     *
     * @param goodsPartId
     * @return
     */
    @Override
    public GoodsQuotationSheetPartProcessDTO queryQuotationSheetPartProcesses(Long goodsPartId) {
        SysOrderProcess sysOrderProcess = super.getOne(new LambdaQueryWrapper<SysOrderProcess>()
                .eq(SysOrderProcess::getOrderPartId, goodsPartId)
        );
        if (sysOrderProcess == null) {
            // 初始化数据
            GoodsQuotationSheetPartProcessDTO goodsProcessVO = new GoodsQuotationSheetPartProcessDTO();
            goodsProcessVO.setTotalProcessCosts(null);

            // 设置默认利润率
            goodsProcessVO.setProfit("12.5");
            goodsProcessVO.setProcessingFee(null);
            goodsProcessVO.setMagnification(null);
            goodsProcessVO.setTotalLaborCost(null);
            goodsProcessVO.setProcessItems(new ArrayList<>());
            return goodsProcessVO;
        }


        List<GoodsQuotationSheetPartProcessDTO.ProcessItemVO> processItemVOS = this.orderProcessItemService.list(new LambdaQueryWrapper<SysOrderProcessItem>()
                .eq(SysOrderProcessItem::getOrderProcessId, sysOrderProcess.getId())
        ).stream().map(x -> {
            GoodsQuotationSheetPartProcessDTO.ProcessItemVO processItemVO = new GoodsQuotationSheetPartProcessDTO.ProcessItemVO();
            processItemVO.setId(x.getId());
            processItemVO.setProcessName(x.getProcessName());
            processItemVO.setWage(x.getWage());
            processItemVO.setRemark(x.getRemark());
            return processItemVO;
        }).collect(Collectors.toList());


        // 计算工价合计
        BigDecimal totalLaborCost = processItemVOS.stream().map(x -> new BigDecimal(x.getWage())).reduce(BigDecimal.ZERO, BigDecimal::add);
//        totalLaborCost = NumberUtil.round(totalLaborCost, 2);

        // 倍率
        BigDecimal magnification = new BigDecimal(StrUtil.blankToDefault(sysOrderProcess.getMagnification(), "0"));

        // 利润率
        BigDecimal profit = NumberUtil.div(StrUtil.blankToDefault(sysOrderProcess.getProfit(), "0"), "100");

        // 计算加工费
        BigDecimal processingFee = NumberUtil.mul(totalLaborCost, magnification);

        // 计算工序费用合计
        BigDecimal totalProcessCosts = NumberUtil.mul(processingFee, NumberUtil.add(new BigDecimal(1), profit));

        GoodsQuotationSheetPartProcessDTO sheetPartProcessDTO = new GoodsQuotationSheetPartProcessDTO();
        sheetPartProcessDTO.setTotalProcessCosts(NumberUtil.round(totalProcessCosts, 2).toPlainString());
        sheetPartProcessDTO.setProfit(sysOrderProcess.getProfit());
        sheetPartProcessDTO.setProcessingFee(NumberUtil.round(processingFee, 2).toPlainString());
        sheetPartProcessDTO.setMagnification(sysOrderProcess.getMagnification());
        sheetPartProcessDTO.setTotalLaborCost(NumberUtil.round(totalLaborCost, 2).toPlainString());
        sheetPartProcessDTO.setRemark(sysOrderProcess.getRemark());
        sheetPartProcessDTO.setProcessItems(processItemVOS);
        return sheetPartProcessDTO;
    }

    /**
     * 计算工价
     *
     * @param calculateWages
     * @return
     */
    @Override
    public String calculateWages(CalculateWagesDTO calculateWages) {
        List<SysOrderProcess> sysOrderProcess = super.list(new LambdaQueryWrapper<SysOrderProcess>()
                .eq(SysOrderProcess::getProduceOrderId, calculateWages.getProduceOrderId())
        );
        Assert.notEmpty(sysOrderProcess, "未获取到该订单中的工序信息");

        List<Long> orderProcessIds = sysOrderProcess.stream().map(BaseEntity::getId).collect(Collectors.toList());
        BigDecimal wages = this.orderProcessItemService.list(new LambdaQueryWrapper<SysOrderProcessItem>()
                        .in(SysOrderProcessItem::getOrderProcessId, orderProcessIds)
                ).stream().map(SysOrderProcessItem::getWage)
                .map(BigDecimal::new)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal result = NumberUtil.mul(wages, NumberUtil.toBigDecimal(calculateWages.getPriceMultiple()));
        return result.stripTrailingZeros().toPlainString();
    }
}
